package com.xqkj.commons.importer.impl;

import com.xqkj.commons.basic.ComponentHolder;
import com.xqkj.commons.constant.HandleResultCode;
import com.xqkj.commons.importer.ExcelFileReader;
import com.xqkj.commons.importer.ExcelFileReaderCallBack;
import com.xqkj.commons.importer.ExcelHeaderRowReader;
import com.xqkj.commons.importer.model.*;
import com.xqkj.commons.model.HandleResult;
import com.xqkj.commons.proxy.ProxyObjAware;
import com.xqkj.commons.utils.Assert;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

import java.util.ArrayList;
import java.util.List;

/**
 * @ Author     ：lwt-mac<br>
 * @ Date       ：2019/7/9 9:49 PM <br>
 * @ Description：<br>
 * @ Modified By：<br>
 * @Version: 1.000
 */
public class DefExcelFileReader extends ProxyObjAware<ExcelFileReader> implements ExcelFileReader {

    private ComponentHolder componentHolder;

    @Override
    public HandleResult<ExcelReadResult> readExcelData(Workbook workbook, String sheetName,
                                                       ExcelHeaderReadConfig excelHeaderReadConfig,
                                                       ExcelBodyRowListReadConfig excelBodyRowListReadConfig,
                                                       ExcelFileReaderCallBack excelFileReaderCallBack, ExcelReadExtInfoVO excelReadExtInfoVO) {

        Sheet sheet=null;
        if(StringUtils.isNotBlank(sheetName)){
            sheet=workbook.getSheet(sheetName);
        }
        if(sheet==null){
            sheet=workbook.getSheetAt(0);
        }
        //读取表头数据
        HandleResult<ExcelReadResult> readExcelHeaderResult = getProxyObjOrThis().readExcelHeader(sheet,excelHeaderReadConfig,
                excelFileReaderCallBack,excelReadExtInfoVO);
        if(!readExcelHeaderResult.isSuccess()){
            return readExcelHeaderResult;
        }
        //准备读取表体数据的参数
        Assert.isNotNull(readExcelHeaderResult.getEntry(),"表头数据返回异常，读取结果不存在");
        ExcelRowReadInfoVO excelHeaderRowReadInfoVO=readExcelHeaderResult.getEntry().getExcelHeaderRowReadInfoVO();
        int bodyStartRow=readExcelHeaderResult.getEntry().getNextRowIndex();
        excelBodyRowListReadConfig=excelBodyRowListReadConfig==null?new ExcelBodyRowListReadConfig():excelBodyRowListReadConfig;
        if(bodyStartRow>excelBodyRowListReadConfig.getCurrentRowIndex()){
            excelBodyRowListReadConfig.setCurrentRowIndex(bodyStartRow);
        }
        //读取表体数据
        HandleResult<ExcelReadResult> readExcelRowListResult = getProxyObjOrThis().readExcelRowList(sheet,excelBodyRowListReadConfig,excelHeaderRowReadInfoVO,
                excelFileReaderCallBack,excelReadExtInfoVO);
        if(!readExcelHeaderResult.isSuccess()){
            return readExcelHeaderResult;
        }
        excelFileReaderCallBack.callReadExcelOver(workbook,sheetName,excelReadExtInfoVO,readExcelHeaderResult);
        //
        return readExcelRowListResult;
    }

    @Override
    public HandleResult<ExcelReadResult> readExcelHeader(Sheet sheet, ExcelHeaderReadConfig excelHeaderReadConfig,
                                                         ExcelFileReaderCallBack excelFileReaderCallBack,
                                                         ExcelReadExtInfoVO excelReadExtInfoVO) {
        ExcelHeaderRowReader excelHeaderRowReader=componentHolder.getComponentByName(excelReadExtInfoVO.getExcelHeaderRowReaderName(),
                ExcelHeaderRowReader.class);
        //读取数据
        HandleResult<ExcelReadResult> readHeaderResult=excelHeaderRowReader.doReadHeaderRowDate(sheet,
                excelHeaderReadConfig, excelReadExtInfoVO);
        //处理数据
        HandleResult<ExcelReadResult> callbackResult=excelFileReaderCallBack.callReadHeaderOver(sheet,
                excelHeaderReadConfig,excelReadExtInfoVO,readHeaderResult);
        //
        return callbackResult;
    }

    @Override
    public HandleResult<ExcelReadResult> readExcelRowList(Sheet sheet, ExcelBodyRowListReadConfig excelBodyRowListReadConfig,
                                                          ExcelRowReadInfoVO excelHeaderRowReadInfoVO,
                                                          ExcelFileReaderCallBack excelFileReaderCallBack,
                                                          ExcelReadExtInfoVO excelReadExtInfoVO) {
        ExcelReadResult excelReadRowListResult=new ExcelReadResult();
        List<ExcelRowReadInfoVO> excelBodyRowReadInfoVOList=new ArrayList<>();
        excelReadRowListResult.setExcelBodyRowReadInfoVOList(excelBodyRowReadInfoVOList);
        int rowIndex=excelBodyRowListReadConfig.getCurrentRowIndex();
        int cellStartIndex=excelBodyRowListReadConfig.getCurrentCellStartIndex();
        while (true){
            Row row=sheet.getRow(rowIndex);
            HandleResult<ExcelReadResult> readRowResult=getProxyObjOrThis().readExcelRow(row,cellStartIndex,excelHeaderRowReadInfoVO,
                    excelFileReaderCallBack,excelReadExtInfoVO);
            //
            if(!readRowResult.isSuccess() && HandleResultCode.NO_DATE_READ.getCode()==readRowResult.getCode()){
                break;
            }
            ExcelReadResult excelReadResult=readRowResult.getEntry();
            if(excelReadResult.getExcelTmpBodyRowReadInfoVO()!=null){
                excelReadResult.getExcelTmpBodyRowReadInfoVO().setCurrentRowIndex(rowIndex);
                excelBodyRowReadInfoVOList.add(excelReadResult.getExcelTmpBodyRowReadInfoVO());
            }
            rowIndex++;
        }
        excelReadRowListResult.setExcelHeaderRowReadInfoVO(excelHeaderRowReadInfoVO);
        return HandleResult.success(excelReadRowListResult);
    }

    @Override
    public HandleResult<ExcelReadResult> readExcelRow(Row row, int cellStartIndex,
                                                      ExcelRowReadInfoVO excelHeaderRowReadInfoVO,
                                                      ExcelFileReaderCallBack excelFileReaderCallBack,
                                                      ExcelReadExtInfoVO excelReadExtInfoVO) {
        int cellIndex=cellStartIndex;
        ExcelReadResult excelReadResult=new ExcelReadResult();
        ExcelRowReadInfoVO excelTmpBodyRowReadInfoVO=new ExcelRowReadInfoVO();
        excelReadResult.setExcelTmpBodyRowReadInfoVO(excelTmpBodyRowReadInfoVO);
        List<ExcelRowCellReadInfoVO> cellInfoVOList=new ArrayList<>();
        excelTmpBodyRowReadInfoVO.setCellInfoVOList(cellInfoVOList);
        while (true){
            Cell cell=row.getCell(cellIndex);
            HandleResult<ExcelReadResult> readCellResult=getProxyObjOrThis().readExcelRowCell(cell,
                    excelHeaderRowReadInfoVO, excelReadExtInfoVO);
            if(!readCellResult.isSuccess() && HandleResultCode.NO_DATE_READ.getCode()==readCellResult.getCode()){
                break;
            }
            if(readCellResult.getEntry()!=null && readCellResult.getEntry().getExcelTmpRowCellReadInfoVO()!=null){
                cellInfoVOList.add(readCellResult.getEntry().getExcelTmpRowCellReadInfoVO());
            }
            cellIndex++;
        }
        if(CollectionUtils.isEmpty(cellInfoVOList)){
            return HandleResult.failed(HandleResultCode.NO_DATE_READ.getCode());
        }
        return HandleResult.success(excelReadResult);
    }

    @Override
    public HandleResult<ExcelReadResult> readExcelRowCell(Cell cell, ExcelRowReadInfoVO excelHeaderRowReadInfoVO,
                                                          ExcelReadExtInfoVO excelReadExtInfoVO) {
        return null;
    }

    @Override
    public void setComponentHolder(ComponentHolder componentHolder) {

    }

    private boolean readBodyRowListOver(){
        return true;
    }
}
